home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Amiga Plus 1995 #2
/
Amiga Plus CD - 1995 - No. 2.iso
/
pd
/
grafik
/
mandelsquare-ham
/
saveilbm.c
< prev
next >
Wrap
C/C++ Source or Header
|
1995-04-11
|
10KB
|
449 lines
/** Revision Header * Header built automatically - do not edit! *************
*
* (C) Copyright 1991 by Olaf `Olsen' Barthel, all rights reserved
*
* Name .....: SaveILBM.c
* Created ..: Monday 26-Aug-91 11:20
* Revision .: 1
*
* Date Author Comment
* ========= ======== ====================
* 26-Aug-91 Olsen Created this file!
*
***************************************************************************/
/* This is basically Jim Kent's IFF-ILBM writer code as published
* in `Plop', with changes for iffparse.library and 32 bit viewmode
* CAMG chunks. I also added a version chunk to be saved with each
* image.
*/
#define DUMP 0
#define RUN 1
#define MINRUN 3
#define MAXRUN 128
#define MAXDAT 128
#define IFF_SIZE 4096
STATIC UBYTE IFFBuffer[IFF_SIZE];
STATIC WORD IFFSize;
STATIC BYTE __regargs
FlushIFF(struct IFFHandle *IFFHandle)
{
if(IFFSize)
{
if(WriteChunkBytes(IFFHandle,IFFBuffer,IFFSize) != IFFSize)
{
IFFSize = 0;
return(FALSE);
}
IFFSize = 0;
}
return(TRUE);
}
STATIC BYTE __regargs
PutIFF(struct IFFHandle *IFFHandle,UBYTE c)
{
if(IFFSize == IFF_SIZE)
if(!FlushIFF(IFFHandle))
return(FALSE);
IFFBuffer[IFFSize++] = c;
return(TRUE);
}
STATIC BYTE __regargs
WriteIFF(struct IFFHandle *IFFHandle,UBYTE *Data,LONG Size)
{
LONG Len;
while(Size)
{
if(IFFSize == IFF_SIZE)
if(!FlushIFF(IFFHandle))
return(FALSE);
if((Len = Size) > IFF_SIZE - IFFSize)
Len = IFF_SIZE - IFFSize;
CopyMem(&Data[0],&IFFBuffer[IFFSize],Len);
IFFSize += Len;
Size -= Len;
Data = &Data[Len];
}
return(TRUE);
}
STATIC LONG __regargs
PackRow(struct IFFHandle *FileHandle,UBYTE *Source,LONG Size)
{
UBYTE c,LastByte = 0,LineBuf[MAXDAT * 3 / 2];
BYTE CompMode = DUMP;
WORD InBuf = 1,RunStart = 0;
LONG PutSize = 0;
LineBuf[0] = LastByte = *Source++;
Size--;
for( ; Size ; --Size)
{
LineBuf[InBuf++] = c = *Source++;
switch(CompMode)
{
case DUMP: if(InBuf > MAXDAT)
{
if(!PutIFF(FileHandle,InBuf-2))
return(FALSE);
if(!WriteIFF(FileHandle,LineBuf,InBuf-1))
return(0);
PutSize += InBuf;
LineBuf[0] = c;
InBuf = 1;
RunStart = 0;
break;
}
if(c == LastByte)
{
if(InBuf - RunStart >= MINRUN)
{
if(RunStart > 0)
{
if(!PutIFF(FileHandle,RunStart-1))
return(FALSE);
if(!WriteIFF(FileHandle,LineBuf,RunStart))
return(0);
PutSize += RunStart+1;
}
CompMode = RUN;
}
else
{
if(!RunStart)
CompMode = RUN;
}
}
else
RunStart = InBuf - 1;
break;
case RUN: if((c != LastByte) || (InBuf - RunStart > MAXRUN))
{
if(!PutIFF(FileHandle,-(InBuf - RunStart - 2)))
return(FALSE);
if(!PutIFF(FileHandle,LastByte))
return(FALSE);
PutSize += 2;
LineBuf[0] = c;
InBuf = 1;
RunStart = 0;
CompMode = DUMP;
}
break;
}
LastByte = c;
}
switch(CompMode)
{
case DUMP: if(!PutIFF(FileHandle,InBuf-1))
return(FALSE);
if(!WriteIFF(FileHandle,LineBuf,InBuf))
return(FALSE);
PutSize += InBuf+1;
break;
case RUN: if(!PutIFF(FileHandle,-(InBuf - RunStart - 1)))
return(FALSE);
if(!PutIFF(FileHandle,LastByte))
return(FALSE);
PutSize += 2;
break;
}
return(PutSize);
}
STATIC LONG __regargs
PackBitMap(struct IFFHandle *FileHandle,struct BitMap *BitMap,LONG Height)
{
LONG i,j,RowLength,CompressedLength = 0,PlaneOffset = 0;
for(i = 0 ; i < Height ; i++)
{
for(j = 0 ; j < BitMap -> Depth ; j++)
{
if(!(RowLength = PackRow(FileHandle,BitMap -> Planes[j] + PlaneOffset,BitMap -> BytesPerRow)))
return(0);
CompressedLength += RowLength;
}
PlaneOffset += BitMap -> BytesPerRow;
}
return(CompressedLength);
}
STATIC BYTE __regargs
WriteILBM(UBYTE *FileName,UBYTE *Colours,struct BitMap *BitMap,LONG OffsetX,BYTE OffsetY,LONG Width,LONG Height,LONG Compressed,LONG PageWidth,LONG PageHeight,ULONG ViewModes,struct MandelInfo *MandelInfo)
{
struct IFFHandle *FileHandle;
struct BitMapHeader BitMapHeader;
LONG RowOffset;
LONG i,j;
WORD NumColours = 32;
BYTE Success = TRUE;
if(BitMap)
{
if((NumColours = 1 << BitMap -> Depth) > 32)
NumColours = 32;
if(ViewModes & HAM)
NumColours = 16;
}
if(FileHandle = AllocIFF())
{
if(FileHandle -> iff_Stream = Open(FileName,MODE_NEWFILE))
{
InitIFFasDOS(FileHandle);
if(!OpenIFF(FileHandle,IFFF_WRITE))
{
if(!PushChunk(FileHandle,'ILBM','FORM',IFFSIZE_UNKNOWN))
{
BitMapHeader . masking = 0;
BitMapHeader . pad1 = 0;
BitMapHeader . transparentColor = 0;
if(Compressed)
BitMapHeader . compression = 1;
else
BitMapHeader . compression = 0;
BitMapHeader . pageWidth = PageWidth;
BitMapHeader . pageHeight = PageHeight;
BitMapHeader . yAspect = 11;
ViewModes &= ~(SPRITES | VP_HIDE | GENLOCK_AUDIO | GENLOCK_VIDEO);
if((ViewModes & HIRES) && (ViewModes & LACE))
BitMapHeader . xAspect = 10;
if(!(ViewModes & HIRES) && (ViewModes & LACE))
BitMapHeader . xAspect = 20;
if((ViewModes & HIRES) && !(ViewModes & LACE))
BitMapHeader . xAspect = 5;
if(!(ViewModes & HIRES) && !(ViewModes & LACE))
BitMapHeader . xAspect = 10;
if(BitMap)
{
BitMapHeader . w = Width;
BitMapHeader . h = Height;
BitMapHeader . nPlanes = BitMap -> Depth;
BitMapHeader . x = OffsetX;
BitMapHeader . y = OffsetY;
}
if(!PushChunk(FileHandle,0,'BMHD',IFFSIZE_UNKNOWN))
{
if(WriteChunkBytes(FileHandle,&BitMapHeader,sizeof(BitMapHeader)) == sizeof(BitMapHeader))
{
if(!PopChunk(FileHandle))
{
if(!PushChunk(FileHandle,0,'CMAP',IFFSIZE_UNKNOWN))
{
if(WriteChunkBytes(FileHandle,Colours,3 * NumColours) == 3 * NumColours)
{
if(!PopChunk(FileHandle))
{
if(!PushChunk(FileHandle,0,'CAMG',IFFSIZE_UNKNOWN))
{
if(WriteChunkBytes(FileHandle,&ViewModes,sizeof(ULONG)) == sizeof(ULONG))
{
if(!PopChunk(FileHandle))
{
if(!PushChunk(FileHandle,0,'MAND',IFFSIZE_UNKNOWN))
{
if(WriteChunkBytes(FileHandle,MandelInfo,sizeof(struct MandelInfo)) == sizeof(struct MandelInfo))
{
if(!PopChunk(FileHandle))
{
if(!PushChunk(FileHandle,0,'ANNO',IFFSIZE_UNKNOWN))
{
extern UBYTE VersTag[];
UBYTE Len;
Len = strlen(&VersTag[1]);
if(WriteChunkBytes(FileHandle,&VersTag[1],Len) != Len)
Success = FALSE;
else
{
if(PopChunk(FileHandle))
Success = FALSE;
}
}
if(Success)
{
if(!PushChunk(FileHandle,0,'BODY',IFFSIZE_UNKNOWN))
{
if(Compressed)
{
if(!PackBitMap(FileHandle,BitMap,Height))
Success = FALSE;
else
{
if(!FlushIFF(FileHandle))
Success = FALSE;
}
}
else
{
i = Height;
RowOffset = 0;
while(--i >= 0 && Success)
{
for(j = 0 ; j < BitMap -> Depth ; j++)
{
if(WriteChunkBytes(FileHandle,BitMap -> Planes[j] + RowOffset,Height) != Height)
{
Success = FALSE;
break;
}
RowOffset += BitMap -> BytesPerRow;
}
}
}
if(PopChunk(FileHandle))
Success = FALSE;
}
}
else
Success = FALSE;
}
else
Success = FALSE;
}
else
Success = FALSE;
}
else
Success = FALSE;
}
else
Success = FALSE;
}
else
Success = FALSE;
}
else
Success = FALSE;
}
else
Success = FALSE;
}
else
Success = FALSE;
}
else
Success = FALSE;
}
else
Success = FALSE;
}
else
Success = FALSE;
}
else
Success = FALSE;
if(PopChunk(FileHandle))
Success = FALSE;
}
else
Success = FALSE;
}
else
Success = FALSE;
Close(FileHandle -> iff_Stream);
}
else
Success = FALSE;
FreeIFF(FileHandle);
}
else
Success = FALSE;
return(Success);
}
LONG
SaveBitMap(struct BitMap *BitMap,struct ViewPort *VPort,LONG LeftEdge,LONG TopEdge,LONG Width,LONG Height,LONG ParentWidth,LONG ParentHeight,STRPTR Name,struct MandelInfo *MandelInfo)
{
extern struct GfxBase *GfxBase;
UBYTE ColTable[32 * 3];
LONG IFF_Result,i,r,g,b;
IFFSize = 0;
for(i = 0 ; i < 32 ; i++)
{
UWORD TmpCol = GetRGB4(VPort -> ColorMap,i);
r = (TmpCol >> 8) & 0xF;
g = (TmpCol >> 4) & 0xF;
b = (TmpCol ) & 0xF;
ColTable[i * 3 + 0] = r << 4;
ColTable[i * 3 + 1] = g << 4;
ColTable[i * 3 + 2] = b << 4;
}
if(!(IFF_Result = WriteILBM(Name,ColTable,BitMap,LeftEdge,TopEdge,Width,Height,TRUE,ParentWidth,ParentHeight,GetVPModeID(VPort),MandelInfo)))
DeleteFile(Name);
else
SetProtection(Name,FIBF_EXECUTE);
return(IFF_Result);
}